package org.arnetminer.personalized.dao;

import java.sql.SQLException;
import java.util.List;

import org.arnetminer.personalized.vo.Event;
import org.arnetminer.personalized.vo.EventType;
import org.arnetminer.personalized.vo.Notification;
import org.arnetminer.personalized.vo.User;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

public class EventDAOImpl extends BaseDAOImpl implements EventDAO {

	private static final Logger log = LoggerFactory.getLogger(EventDAOImpl.class);
	
	public void initDao() {
		super.initDao();
	}
	
	
	public void save(Event transientInstance) {
		super.save(transientInstance);
	}

	
	public void delete(Event persistentInstance) {
		super.delete(persistentInstance);
	}

	
	public List findByExample(Event instance) {
		return super.findByExample(instance);
	}


	public Object merge(Event detachedInstance) {
		return super.merge(detachedInstance);
	}


	public void attachDirty(Event instance) {
		super.attachDirty(instance);
	}

	
	public void attachClean(Event instance) {
		super.attachClean(instance);
	}
	
	@Override
	public EventType findEventTypeById(long id) {
		log.debug("getting EventType instance with id: " + id);
        try {
        	EventType instance = (EventType) getHibernateTemplate()
                    .get("org.arnetminer.personalized.vo.EventType", id);
            return instance;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
	}


	@Override
	public void saveNotification(Notification transientInstance) {
		super.save(transientInstance);
	}
	
	@Override
	public List findEventsByProperties(final List<String> properties, final List values, final int start, final int max) {
		log.debug("finding Event instance within range\n");
	      try {
		    	HibernateTemplate template = getHibernateTemplate();
		    	return template.executeFind(new HibernateCallback() {  
		            public Object doInHibernate(Session session) throws HibernateException, SQLException {
		            	try {
		            	Criteria criteria = session.createCriteria(Event.class);
		            	for (int i = 0; i < properties.size(); i++) {
		            		criteria.add(Restrictions.eq(properties.get(i), values.get(i)));
		    	    	}
		            	criteria.addOrder(Order.desc("id"));
		            	criteria.setFirstResult(start);
		            	criteria.setMaxResults(max);
		            	return criteria.list();
		            	}
		            	catch(Exception ex) {
		            		ex.printStackTrace();
		            		return null;
		            	}
		            	finally {
		            		session.close();
		            	}
		            }  
		        });
		    } catch (RuntimeException re) {
		       log.error("find by property name failed", re);
		       throw re;
		    }
	}
	
	@Override
	public List findNotificationsByProperties(final List<String> properties, final List values, final int start, final int max) {
		log.debug("finding Notification instance within range\n");
	      try {
		    	HibernateTemplate template = getHibernateTemplate();
		    	return template.executeFind(new HibernateCallback() {  
		            public Object doInHibernate(Session session) throws HibernateException, SQLException {
		            	try {
		            	Criteria criteria = session.createCriteria(Notification.class);
		            	for (int i = 0; i < properties.size(); i++) {
		            		criteria.add(Restrictions.eq(properties.get(i), values.get(i)));
		    	    	}
		            	criteria.addOrder(Order.desc("id"));
		            	criteria.setFirstResult(start);
		            	criteria.setMaxResults(max);
		            	return criteria.list();
		            	}
		            	catch(Exception ex) {
		            		ex.printStackTrace();
		            		return null;
		            	}
		            	finally {
		            		session.close();
		            	}
		            }  
		        });
		    } catch (RuntimeException re) {
		       log.error("find by property name failed", re);
		       throw re;
		    }
	}
	
	@Override
	public void deleteNotification(Notification persistentInstance) {
		super.delete(persistentInstance);
	}

	@Override
	public Event findEventById(long id) {
        log.debug("getting Event instance with id: " + id);
        try {
        	Event instance = (Event) getHibernateTemplate()
                    .get("org.arnetminer.personalized.vo.Event", id);
            return instance;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
    }
	
	

}
